package com.bosssoft.boss_exam_web.Controller;

import com.bosssoft.boss_exam_core.enums.business.ExamPaperCheckEnum;
import com.bosssoft.boss_exam_core.exception.BusinessException;
import com.bosssoft.boss_exam_core.exception.UpdateEntityException;
import com.bosssoft.boss_exam_core.storage.StorageService;
import com.bosssoft.boss_exam_core.util.base64ImgUtil.Base64ImgUtil;
import com.bosssoft.boss_exam_core.util.common.CharUtil;
import com.bosssoft.boss_exam_core.util.json.JsonUtil;
import com.bosssoft.boss_exam_core.util.web.ResponseUtil;
import com.bosssoft.boss_exam_db.entity.*;
import com.bosssoft.boss_exam_db.service.busines.*;
import com.bosssoft.boss_exam_web.common.annotation.LoginApplicant;
import com.bosssoft.boss_exam_web.model.dto.questionImg.MyFileMetadata;
import com.bosssoft.boss_exam_web.model.dto.questionImg.PhoneImgObjDTO;
import com.bosssoft.boss_exam_web.model.dto.questionImg.QuestionAnswerImgDTO;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

@RestController
@Slf4j
public class UploadBase64ImgController {

    //    引入应聘者服务
    @Autowired
    private ApplicantService applicantService;

    //    引入存储服务
    @Autowired
    private StorageService storageService;

    //    引入文件对象存储元数据服务
    @Autowired
    private FilemetadataService filemetadataService;

    //    引入应聘人问题-答案服务
    @Autowired
    private ApplicantQuestionScoreService applicantQuestionScoreService;

    //    引入应聘人-试卷服务
    @Autowired
    private ApplicantExamPaperService applicantExamPaperService;

    //    引入考试-试卷服务
    @Autowired
    private ExamExamPaperService examExamPaperService;

    //引入事务管理器
    @Autowired
    @Qualifier("transactionManager")
    private PlatformTransactionManager transactionManager;

    @ApiOperation(value = "手机考试", notes = "手机端考试", httpMethod = "GET", response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "questionAnswerImgDTOS", value = "手机考试包含图片", dataType = "QuestionAnswerImgDTO[]", required = true, dataTypeClass = QuestionAnswerImgDTO[].class),
    })
    @PostMapping("/phone/img")
    public Object uploadBase64Img(@LoginApplicant String applicantId, @RequestBody QuestionAnswerImgDTO[] questionAnswerImgDTOS) throws UnsupportedEncodingException {

//       引入编程事务
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
//       设置事务传播行为：required 如有事务加入事务，无事务新建一起事务
//       作用将多个service操作都使用同一个connection事务
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        TransactionStatus status = transactionManager.getTransaction(defaultTransactionDefinition);
        try {
            if (applicantId == null) {
                return ResponseUtil.unlogin();
            }
            String examId = null;
            String examPaperId = null;
            Applicant applicant = applicantService.getApplicantById(applicantId);
            List<ApplicantQuestionScore> applicantQuestionScores = new ArrayList<>();
            if (questionAnswerImgDTOS != null && questionAnswerImgDTOS.length != 0) {
                Arrays.stream(questionAnswerImgDTOS).forEach(questionAnswerImgDTO -> {
                    List<PhoneImgObjDTO> phoneImgObjDTOList = questionAnswerImgDTO.getPhoneImgObjDTOList();
                    // 存放图片的url
                    ArrayList<String> imglist = new ArrayList<>();
                    // 保存图片
                    if (phoneImgObjDTOList != null && phoneImgObjDTOList.size() > 0) {
                        phoneImgObjDTOList.stream().forEach(item -> {
                            String base64ImgSrc = item.getBase64ImgSrc();
                            MyFileMetadata myFileMetadata = item.getMyFileMetadata();
                            String originalFilename = myFileMetadata.getName();
                            Integer size = myFileMetadata.getSize();
                            String type = myFileMetadata.getType();
                            String key = generateKey(originalFilename);
                            // 保存资源记录到资源文件管理表
                            // 保存图片到服务器文件夹下
                            String realStr = base64ImgSrc.substring(base64ImgSrc.indexOf(",") + 1);
                            byte[] bytes = Base64ImgUtil.ImgStrChange2InputStream(realStr);
                            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
                            String url = storageService.store(inputStream, size, type, originalFilename);
                            imglist.add(url);
                        });
                    }
                    // 保存数据
                    ApplicantQuestionScore applicantQuestionScore = new ApplicantQuestionScore();
                    BeanUtils.copyProperties(questionAnswerImgDTO, applicantQuestionScore);
                    // 补充提交试卷的应聘者
                    applicantQuestionScore.setApplicantId(applicant.getId());
                    // 上传的图片地址列表
                    String imgUrlsJsonStr = JsonUtil.object2Json(imglist);
                    // 设置试卷ID
                    // 根据考试ID查询试卷ID
                    // fixme 前台设计出问题在dto中没examPaperId导致后台插入前需查询试卷ID（试卷ID必须不为空，否则影响其他业务）
                    String tmpExamPaperId = null;
                    String examId1 = questionAnswerImgDTO.getExamId();
                    List<ExamExamPaper> examExamPapers = examExamPaperService.queryExamPaperByExamId(examId1);
                    if (examExamPapers != null && examExamPapers.size() > 0) {
                        tmpExamPaperId = examExamPapers.get(0).getExamPaperId();
                    }
                    applicantQuestionScore.setExamPaperId(tmpExamPaperId);
                    applicantQuestionScore.setAnswerImg(imgUrlsJsonStr);
                    applicantQuestionScores.add(applicantQuestionScore);
                });
            }
            Boolean result = false;
            try {
                // 保存应聘人答题记录
                result = applicantQuestionScoreService.insertApplicantQuestionScoreList(applicantQuestionScores);
                // 获取考试ID和试卷ID
                if (applicantQuestionScores != null && applicantQuestionScores.get(0) != null) {
                    examId = applicantQuestionScores.get(0).getExamId();
                    examPaperId = applicantQuestionScores.get(0).getExamPaperId();
                }
                // 查询该考试的阅卷官列表
                List<ExamExamPaper> examExamPapers = examExamPaperService.queryByExamIdAndExamPaper(examId, examPaperId);
                if (examExamPapers == null || examExamPapers.get(0) == null) {
                    log.error("【业务错误】 没有该考试-试卷对应记录");
                    throw new BusinessException("没有该考试-试卷对应记录");
                }
                ExamExamPaper examExamPaper = examExamPapers.get(0);
                String adminIdArr1 = examExamPaper.getAdminIdArr();
                List adminIdList = JsonUtil.json2Object(adminIdArr1, List.class);
                //随机范围在0~size-1
                int randomIndex = (int) (new Random().nextInt(adminIdList.size()));
                String adminId = (String) adminIdList.get(randomIndex);
                // 保存应聘人答题
                ApplicantExamPaper applicantExamPaper = new ApplicantExamPaper();
                applicantExamPaper.setExamId(examId);
                applicantExamPaper.setApplicantId(applicantId);
                applicantExamPaper.setExamPaperId(examPaperId);
                applicantExamPaper.setCheckPeopleId(adminId);
                applicantExamPaper.setChecked(ExamPaperCheckEnum.NO_CHECK.getCode());
                int i = applicantExamPaperService.saveNotNull(applicantExamPaper);
            } catch (Exception e) {
                log.error("【系统错误】 提交答案失败" + e);
                throw new UpdateEntityException();
            }
            // 事务提交
            transactionManager.commit(status);
            return ResponseUtil.ok();
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw new UpdateEntityException(e);
        }
    }


    /***
     * @Author lys(cherish)
     * @Phone 17720799636
     * @Date  2019/4/7
     * @Description 根据文件名生成随机串
     * @Param [originalFilename] 原文件名
     * @Return java.lang.String
     * @Exception
     * @since JDK 1.8
     **/
    private String generateKey(String originalFilename){
        int index = originalFilename.lastIndexOf('.');
        String suffix = originalFilename.substring(index);
        String key = null;
        Filemetadata filemetadata = null;
        do{
            key = CharUtil.getRandomString(20) + suffix;
            filemetadata = filemetadataService.findByKey(key);
        }
        while(filemetadata != null);
        return key;
    }

}
